package com.fingard.dsp.bank.directbank.cdb01;

import java.util.Date;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.DirectBase;
import com.fingard.net.WebRequest;
import com.fingard.text.StringHelper;
import com.fingard.util.TransIDHelper;
import com.fingard.xml.XmlTextWriter;

/**
 * Description: [DSP_国开行基类]
 * Created on 19/03/07
 *
 * @author <a href="mailto:zhangxw@fingard.com.cn">ross</a>
 * @version 1.0
 * Copyright (c) 2019 FinGard
 */
public class CDB01Base extends DirectBase {

    /**
     * 渠道代码
     */
    private final static String CHANNEL = "YQ";
    /**
     * 签名提交地址
     */
    private final static String SIGNPOSTURL = "/debankclient/SignTxControl";
    /**
     * 报文提交地址
     */
    private final static String INFOPOSTURL = "/debankclient/EntTxControl";
    /**
     * 签名信息开始节点
     */
    private final static String SIGNSTARTNODE = "<Signature><DN>";
    /**
     * 签名信息结尾节点
     */
    private final static String SIGNENDNODE = "</DN></Signature></PACKET>";
    /**
     * 签名信息置换节点
     */
    private final static String REPLACENODE = "</PACKET>";

    /**
     * 获取渠道字符编码
     * @return config内charset节点值
     */
    protected String getCharset() {
        return getBankConfig().getCharset("UTF-8");
    }

    /**
     * 写通用公共报文头
     *
     * @param xmlWriter
     * @param tmpBankHeader
     * @throws Exception
     */
    public void writeCommonHead(XmlTextWriter xmlWriter, CDB01Header tmpBankHeader) throws Exception {
        if (StringHelper.isNullOrEmpty(tmpBankHeader.TransCode)) {
            throw new Exception("交易代码未赋值");
        }
        if (StringHelper.isNullOrEmpty(tmpBankHeader.Fseqno)) {
            throw new Exception("指令包序列号为空");
        }
        xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"" + getCharset() + "\"?>");
        xmlWriter.writeStartElement("Packet");
        xmlWriter.writeStartElement("Data");
        xmlWriter.writeStartElement("Pub");
        /**
         * 交易代码	String(10)	M	银企直联交易接口代码，请参考公共代码说明交易代码表
         */
        xmlWriter.writeElementString("TransCode", tmpBankHeader.TransCode);
        /**
         * 企业客户号	String(60)	M	签约企业客户号
         */
        xmlWriter.writeElementString("GID", bankFront.org);
        /**
         * 归属银行编号	String(6)	M	企业归属的分支银行编号
         */
        xmlWriter.writeElementString("BankCode", bankFront.operator);
        /**
         * 交易日期	String(8)	M	格式：YYYYMMDD，年月日
         */
        xmlWriter.writeElementString("TransDate", Format.Date8Format.format(new Date()));
        /**
         * 交易时间	String(6)	M	格式：hhmmss，时分秒
         */
        xmlWriter.writeElementString("TransTime", Format.Time6Format.format(new Date()));
        /**
         * 指令包序列号	String(35)	M	由交易请求发起方定义的序列号，要求具有唯一性。
         */
        xmlWriter.writeElementString("Fseqno", tmpBankHeader.Fseqno);
        xmlWriter.writeEndElement();
        xmlWriter.writeStartElement("Req");
    }

    /**
     * 写通用公共报文头
     *
     * @param xmlWriter
     * @param tmpBankHeader
     * @throws Exception
     */
    public void writeCommonHeadNoReqTag(XmlTextWriter xmlWriter, CDB01Header tmpBankHeader) throws Exception {
        if (StringHelper.isNullOrEmpty(tmpBankHeader.TransCode)) {
            throw new Exception("交易代码未赋值");
        }
        if (StringHelper.isNullOrEmpty(tmpBankHeader.Fseqno)) {
            throw new Exception("指令包序列号为空");
        }
        xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"" + getCharset() + "\"?>");
        xmlWriter.writeStartElement("Packet");
        xmlWriter.writeStartElement("Data");
        xmlWriter.writeStartElement("Pub");
        /**
         * 交易代码	String(10)	M	银企直联交易接口代码，请参考公共代码说明交易代码表
         */
        xmlWriter.writeElementString("TransCode", tmpBankHeader.TransCode);
        /**
         * 企业客户号	String(60)	M	签约企业客户号
         */
        xmlWriter.writeElementString("GID", bankFront.org);
        /**
         * 归属银行编号	String(6)	M	企业归属的分支银行编号
         */
        xmlWriter.writeElementString("BankCode", bankFront.operator);
        /**
         * 交易日期	String(8)	M	格式：YYYYMMDD，年月日
         */
        xmlWriter.writeElementString("TransDate", Format.Date8Format.format(new Date()));
        /**
         * 交易时间	String(6)	M	格式：hhmmss，时分秒
         */
        xmlWriter.writeElementString("TransTime", Format.Time6Format.format(new Date()));
        /**
         * 指令包序列号	String(35)	M	由交易请求发起方定义的序列号，要求具有唯一性。
         */
        xmlWriter.writeElementString("Fseqno", tmpBankHeader.Fseqno);
        xmlWriter.writeEndElement();
        xmlWriter.writeStartElement("Req");
    }

    protected String codeToAscii(String p_Code) throws Exception {
        byte[] Bytes = p_Code.getBytes(getCharset());
        StringBuilder tmpReturnCode = new StringBuilder();
        for (byte b : Bytes) {
            if ((short) b <= 57 && (short) b >= 48) {
                tmpReturnCode.append(String.valueOf((short) b - 48));
            } else {
                tmpReturnCode.append("0" + String.valueOf((short) b));
            }
        }
        if (tmpReturnCode.toString().length() > 6) {
            return tmpReturnCode.toString().substring(tmpReturnCode.toString().length() - 6);
        } else {
            return StringHelper.padLeft(tmpReturnCode.toString(), 6, '0');
        }
    }

    private static TransIDHelper idHelper = new TransIDHelper(1, 999999);

    protected String getQryTransID() {
        return String.format("%s%s%s%s", CHANNEL, bankFront.corpNo, Format.DateTime14Format.format(new Date()), idHelper.getNextIDStr());
    }

    protected String generateSeqNo(Date p_datetime, String p_reqseqID) throws Exception {
        return String.format("%s%s%s%s", CHANNEL, bankFront.corpNo, Format.DateTime14Format.format(p_datetime), codeToAscii(p_reqseqID));
    }

    protected String[] sendToBank(String p_reqStr, boolean needSigned) throws Exception {
        String[] retStr = new String[]{"", ""};
        String tmpAddr = "http://" + bankFront.serverIP + ":" + bankFront.serverPort + (needSigned ? SIGNPOSTURL : INFOPOSTURL);
        if (needSigned) {
            WriteBankLogLn("当前进行签名操作");
        }
        WriteBankUrlLogLn(tmpAddr);
        WriteBankLogStep2(p_reqStr);
        byte[] tmpToWriteBytes = p_reqStr.getBytes(getCharset());
        WebRequest tmpWebRequest = new WebRequest(tmpAddr);
        tmpWebRequest.setConnectTimeout(600000);
        tmpWebRequest.setRequestProperty("Content-Type", "text/xml; charset=UTF-8");

        retStr = tmpWebRequest.upload(tmpToWriteBytes, getCharset());
        WriteBankLogStep3(retStr[1]);
        return retStr;
    }

    protected String appendSignData(String p_originalStr, String p_signResult) {
        String newStr = String.format("%s%s%s", SIGNSTARTNODE, p_signResult, SIGNENDNODE);
        return p_originalStr.replace(REPLACENODE, newStr);
    }
}
